Package org.python.pydev.editor.actions

Source Code of org.python.pydev.editor.actions.PyShiftLeft

/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.python.pydev.editor.actions;

import java.util.List;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.python.pydev.core.IIndentPrefs;
import org.python.pydev.core.docutils.PySelection;
import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.editor.PyEdit;

/**
* This action was created so that we can make the shift left even if there are less characters in the line than
* the expected indent (the default shift left won't do the dedent in that case).
*/
public class PyShiftLeft extends PyAction {

    /**
     * Grabs the selection information and performs the action.
     *
     * Note that setting the rewrite session and undo/redo must be done from the caller.
     */
    public void run(IAction action) {
        try {
            if (!canModifyEditor()) {
                return;
            }

            PyEdit pyEdit = (PyEdit) getTextEditor();
            IIndentPrefs indentPrefs = pyEdit.getIndentPrefs();
            PySelection ps = new PySelection(pyEdit);
            perform(ps, indentPrefs);
        } catch (Exception e) {
            beep(e);
        }
    }

    /**
     * Performs the action with a given PySelection
     *
     * @param ps Given PySelection
     * @param indentPrefs
     * @return the new selection
     * @throws BadLocationException
     */
    public void perform(PySelection ps, IIndentPrefs indentPrefs) throws BadLocationException {
        int endLineIndex = ps.getEndLineIndex();
        int startLineIndex = ps.getStartLineIndex();

        // If they selected a partial line, count it as a full one
        ps.selectCompleteLine();

        String selectedText = ps.getSelectedText();
        List<String> ret = StringUtils.splitInLines(selectedText);

        int tabWidth = indentPrefs.getTabWidth();
        int tabWidthToUse = tabWidth;

        //Calculate the tab width we should use
        for (String line : ret) {
            String lineIndent = PySelection.getIndentationFromLine(line);

            if (lineIndent.length() > 0) {
                if (lineIndent.startsWith("\t")) {
                    //Tab will be treated by removing the whole tab, so, just go on
                } else {
                    //String with spaces... let's see if we have less spaces than we have the tab width
                    int spaces = 0;
                    for (int i = 0; i < lineIndent.length(); i++) {
                        char c = lineIndent.charAt(i);
                        if (c == ' ') {
                            spaces += 1;
                        } else {
                            break; //ok, found all spaces available
                        }
                    }
                    if (spaces > 0) {
                        tabWidthToUse = Math.min(spaces, tabWidthToUse);
                    }
                }
            }
        }

        String defaultIndentStr = StringUtils.createSpaceString(tabWidthToUse);

        //Note that we remove the contents line by line just erasing the needed chars
        //(if we did a full replacement in the end, the cursor wouldn't end in the correct position
        //and trying to set the cursor later also changed the editor scroll position).
        IDocument doc = ps.getDoc();
        for (int i = startLineIndex; i <= endLineIndex; i++) {
            String line = ps.getLine(i);
            if (line.startsWith("\t")) {
                doc.replace(ps.getLineOffset(i), 1, "");

            } else if (line.startsWith(defaultIndentStr)) {
                doc.replace(ps.getLineOffset(i), defaultIndentStr.length(), "");
            }
        }
    }
}
TOP

Related Classes of org.python.pydev.editor.actions.PyShiftLeft

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.